/*
 * Copyright (c) 2025 Bitdefender
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef BDX86_API_LEGACY_H
#define BDX86_API_LEGACY_H

#include "bdx86_core.h"


//
// Operands access map. Contains every register except for MSR & XCR, includes memory, flags, RIP, stack.
// Use NdGetFullAccessMap to populate this structure.
//
typedef struct _ND_ACCESS_MAP
{
    ND_UINT8    RipAccess;
    ND_UINT8    FlagsAccess;
    ND_UINT8    StackAccess;
    ND_UINT8    MemAccess;
    ND_UINT8    MxcsrAccess;
    ND_UINT8    PkruAccess;
    ND_UINT8    SspAccess;
    ND_UINT8    GprAccess[ND_MAX_GPR_REGS];
    ND_UINT8    SegAccess[ND_MAX_SEG_REGS];
    ND_UINT8    FpuAccess[ND_MAX_FPU_REGS];
    ND_UINT8    MmxAccess[ND_MAX_MMX_REGS];
    ND_UINT8    SseAccess[ND_MAX_SSE_REGS];
    ND_UINT8    CrAccess [ND_MAX_CR_REGS ];
    ND_UINT8    DrAccess [ND_MAX_DR_REGS ];
    ND_UINT8    TrAccess [ND_MAX_TR_REGS ];
    ND_UINT8    BndAccess[ND_MAX_BND_REGS];
    ND_UINT8    MskAccess[ND_MAX_MSK_REGS];
    ND_UINT8    TmmAccess[ND_MAX_TILE_REGS];
    ND_UINT8    SysAccess[ND_MAX_SYS_REGS];
    ND_UINT8    X87Access[ND_MAX_X87_REGS];
} ND_ACCESS_MAP, *PND_ACCESS_MAP;


//
// Operand reverse-lookup table. Each entry inside this structure contains the pointer to the relevant operand.
// Some rules govern this special structure:
//  - It is not generated by default. The user must call NdGetOperandRlut manually to fill in this structure.
//  - This structure holds pointers inside the INSTRUX provided to the NdGetOperandRlut function; please make sure
//    you call NdGetOperandRlut again if the INSTRUX is relocated, as all the pointers will dangle.
//  - Not all the operand types have a corresponding entry in ND_OPERAND_RLUT, only the usual ones.
//  - Some operands may have multiple entries in ND_OPERAND_RLUT - for example, RMW (read-modify-write) instructions
//    will have Dst1 and Src1 pointing to the same operand.
//  - The implicit registers entries in ND_OPERAND_RLUT will point to the operand which is of that type, and implicit;
//    for example, ND_OPERAND_RLUT.Rax will be NULL for `add rax, rcx`, since in this case, `rax` is not an implicit
//    operand. For `cpuid`, however, ND_OPERAND_RLUT.Rax will point to the implicit `eax` register.
// Use NdGetOperandRlut to populate this structure.
//
typedef struct _ND_OPERAND_RLUT
{
    PND_OPERAND     Dst1;   // First destination operand.
    PND_OPERAND     Dst2;   // Second destination operand.
    PND_OPERAND     Src1;   // First source operand.
    PND_OPERAND     Src2;   // Second source operand.
    PND_OPERAND     Src3;   // Third source operand.
    PND_OPERAND     Src4;   // Fourth source operand.
    PND_OPERAND     Mem1;   // First memory operand.
    PND_OPERAND     Mem2;   // Second memory operand.
    PND_OPERAND     Stack;  // Stack operand.
    PND_OPERAND     Flags;  // Flags register operand.
    PND_OPERAND     Rip;    // Instruction Pointer register operand.
    PND_OPERAND     Cs;     // Implicit CS operand.
    PND_OPERAND     Ss;     // Implicit SS operand.
    PND_OPERAND     Rax;    // Implicit accumulator register operand.
    PND_OPERAND     Rcx;    // Implicit counter register operand.
    PND_OPERAND     Rdx;    // Implicit data register operand
    PND_OPERAND     Rbx;    // Implicit base address register operand.
    PND_OPERAND     Rsp;    // Implicit stack pointer operand.
    PND_OPERAND     Rbp;    // Implicit base pointer operand.
    PND_OPERAND     Rsi;    // Implicit source index operand.
    PND_OPERAND     Rdi;    // Implicit destination index operand.
} ND_OPERAND_RLUT;


//
// Returns true if the instruction is RIP relative. Note that this function is kept for backwards compatibility, since
// there already is a IsRipRelative field inside INSTRUX.
//
ND_BOOL
NdIsInstruxRipRelative(
    const INSTRUX *Instrux
);

//
// Returns an access map that contains the access for each register.
//
NDSTATUS
NdGetFullAccessMap(
    const INSTRUX *Instrux,
    ND_ACCESS_MAP *AccessMap
);

//
// Returns an operand reverse-lookup. One can use the Rlut to quickly reference different kinds of operands in INSTRUX.
//
NDSTATUS
NdGetOperandRlut(
    const INSTRUX *Instrux,
    ND_OPERAND_RLUT *Rlut
);

#endif // BDX86_API_LEGACY_H
